import com.alibaba.fastjson.JSON

import org.apache.http.message.BasicNameValuePair
import org.apache.http.client.entity.UrlEncodedFormEntity

import org.apache.http.entity.StringEntity
import org.apache.http.entity.ContentType

import org.apache.http.client.methods.HttpUriRequest
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.methods.HttpPost

import org.apache.http.impl.client.DefaultHttpClient
import org.apache.http.util.EntityUtils

class SpecHttpClient {
	public static SpecHttpClient newInstance(){
		return new SpecHttpClient()
	}

	def client = new DefaultHttpClient()

	private String appendUrl(String url, Map values){
		if(!values)
			return url

		def sb = new StringBuffer(url)
		sb << '?'

		values.each{k, v ->
			sb << k
			sb << '='
			sb << URLEncoder.encode(v, SpecConfig.props.encoding)
			sb << '&'
		}

		sb.toString()
	}

	private HttpUriRequest getRequest(String url, String method, Map headers, Map params){
		if(method == 'post'){
			def req = new HttpPost(url)
			if(params['json']){
				req.setEntity(new StringEntity(params['json'], ContentType.APPLICATION_JSON))
			}else if(params['key=value']){
				List list = []
				params['key=value'].each{k, v ->
					list << new BasicNameValuePair(k, v)
				}

				req.setEntity(new UrlEncodedFormEntity(list, SpecConfig.props.encoding))
			}
			return req
		}else{
			url = appendUrl(url, params['key=value'])
			def req = new HttpGet(url)
			return req
		}
	}

	def Map doRequest(String url, String method, Map headers, Map params){
		def req = getRequest(url, method, headers, params)
		headers.each{k, v ->
			req.setHeader(k, v)
		}

		def response = client.execute(req)
		int statusCode = response.statusLine.statusCode

		def entity = response.getEntity()
		String serverText = EntityUtils.toString(entity, SpecConfig.props.encoding)

		SpecLogger.debug serverText

		if(200 == statusCode){
			String contentType = entity.contentType?.value
			return contentType.contains('application/json') ? 
				[data: JSON.parse(serverText)] : [responseText: serverText]
		}else if(302 == statusCode){
			String targetUrl = response.getFirstHeader('Location').value
			return doRequest(targetUrl, 'get', [:], [:])
		}else{
			return [phrase: 'http', ex: new RuntimeException('http request error'), 
				code: statusCode, serverText: serverText]
		}
	}
}
